package com.cskaoyan.aspect;


import com.cskaoyan.annotation.LogAnnotation;
import com.cskaoyan.bean.Admin;
import com.cskaoyan.bean.Log;
import com.cskaoyan.mapper.LogMapper;
import com.cskaoyan.shiro.MallToken;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.mybatis.logging.Logger;
import org.mybatis.logging.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/** 系统日志：切面处理类 */
@Aspect
@Component
public class LogAspect {

    //private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
    // 注入service,用来将日志信息保存在数据库
    @Autowired
    LogMapper logMapper;
//    LogService logService;

    //定义切点 @Pointcut
    //在注解的位置切入代码
    // 配置接入点，即为所要记录的action操作目录
    @Pointcut("@annotation( com.cskaoyan.annotation.LogAnnotation)")
    public void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        //日志实体对象
        Log logBo = new Log();
        Subject subject = SecurityUtils.getSubject();
        MallToken token = (MallToken) subject.getPrincipals().getPrimaryPrincipal();
        String username = token.getUsername();
        //String username = "admin123";
        logBo.setAdmin(username);

        // 获取系统当前时间
        Date date=new Date(System.currentTimeMillis());
        logBo.setAddTime(date);
        logBo.setUpdateTime(date);


        InetAddress localHost = Inet6Address.getLocalHost();
        String ipAddress = localHost.getHostAddress();
//        String ipAddress = "7:7:7:7:7:7:7:7";

        logBo.setIp(ipAddress);

        // 拦截的实体类，就是当前正在执行的controller
        Object target = pjp.getTarget();
        // 拦截的方法名称。当前正在执行的方法
        String methodName = pjp.getSignature().getName();

        // 拦截的方法参数类型
        Signature sig = pjp.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Class[] parameterTypes = msig.getMethod().getParameterTypes();
        Object object = null;
        // 获得被拦截的方法
        Method method = null;
        try {
            method = target.getClass().getMethod(methodName, parameterTypes);
        } catch (NoSuchMethodException e1) {
            e1.printStackTrace();
        } catch (SecurityException e1) {
            e1.printStackTrace();
        }
        if (null != method) {
            // 获取方法（此为自定义注解）
            LogAnnotation op = method.getAnnotation(LogAnnotation.class);
            // 获取注解的modules 设为操作模块
            logBo.setAction(op.module());

            try {
                object = pjp.proceed();
                //1为执行成功
                logBo.setType(1);
                logBo.setStatus(true);
                // 添加到数据库
                logMapper.insertSelective(logBo);
            } catch (Throwable e) {
                //2为执行失败
                logBo.setStatus(false);
                //添加到数据库
                logMapper.insertSelective(logBo);
            }
        }
        return object;
    }


}








